﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;

public abstract class PUEXBaseColliderAffector : PUEXAffector {

	/** Determines how a particle collision should be determined. IT_POINT means that the position of 
        the particle will be validated against the Colliders' shape. IT_BOX means that the dimensions
        (width, height and depth) are used to determine whether the particle collides.
    */
	public enum IntersectionType
	{
		IT_SPHERE,
		IT_BOX,
	};
	
	/** Determines how a particle behaves after collision with this collider. The behaviour of the
        particle is solved in the collider and only behaviour that needs the colliders?data is taken
        into account. The fact that a particle expires for example, can be achieved by using an 
        Observer in combination with an EventHandler (DoExpireEventHandler).
        CT_BOUNCE means that the particle bounces off the collider.
        CT_FLOW means that the particle flows around the contours of the collider.
    */
	public enum CollisionType
	{
		CT_BOUNCE,
		CT_FLOW,
	};

	#region - Editable property
	[Header("Collider:")]
	public IntersectionType intersectionType;
	public CollisionType collisionType;
	[Range(0f, 1f)]
	public float friction;
	[Range(0f, 1f)]
	public float bouncyness;
	public bool deviantRotationAxis;
	public float minKillSpeed;
	public float minFreezeSpeed;
	public bool inWorldSpace;
	#endregion
	
	#region - Lifecycle
	public PUEXBaseColliderAffector ()
	{
		intersectionType = IntersectionType.IT_SPHERE;
		collisionType = CollisionType.CT_BOUNCE;
		friction = 0f;
		bouncyness = 1f;
		deviantRotationAxis = true;
		minKillSpeed = 0f;
		minFreezeSpeed = 0f;
		inWorldSpace = true;
	}
	#endregion

	protected void calculateRotationSpeedAfterCollision(PUEXParticle particle)
	{
		if (deviantRotationAxis)
			particle.rotationAxis = PUEXUtils.randomDeviant (particle.rotationAxis, particle.rotationSpeed);

		float signedFriction = Random.value > 0.5 ? -(friction - 1f) : (friction - 1f);
		particle.rotationSpeed *= signedFriction;
	}

	#region - Serialization
	public override JsonData save (JsonData emitterData, JsonData systemData)
	{
		JsonData ret = base.save (emitterData, systemData);

		if (intersectionType == IntersectionType.IT_SPHERE) {
			ret ["intersection_type"] = "sphere";
		} else if (intersectionType == IntersectionType.IT_BOX) {
			ret ["intersection_type"] = "box";
		}
		if (collisionType == CollisionType.CT_BOUNCE) {
			ret ["collision_type"] = "bounce";
		} else if (collisionType == CollisionType.CT_FLOW) {
			ret ["collision_type"] = "flow";
		}
		ret ["friction"] = friction;
		ret ["bouncyness"] = bouncyness;
		ret ["deviant_rotation_axis"] = deviantRotationAxis;
		ret ["min_kill_speed"] = minKillSpeed;
		ret ["min_freeze_speed"] = minFreezeSpeed;
		ret ["in_world_space"] = inWorldSpace;
		
		return ret;
	}
	#endregion

}
